/***********************************************************
 *  File_Name  : XJField.cpp
 *  File_Path   :
 *  File_Encode : UTF8
 *  Description : Field Class
 *
 *  OS : Linux, UNIX
 *  LastVersion  : 20150115
 *
 *  Author      : LiXiujie(李秀杰)
 *  Date        : 2015-1-15
 *  Version     : 20150115
 *  Description :
 *
 *  Edit Author :
 *  Edit Date   :
 *  Version     :
 *  Description :
 *
 ***********************************************************/

#include "XJField.h"

#include "XJStringUtil.h"
#include "XJHexString.h"

#ifdef XJF_JSON
#include "json.h"
#endif
#ifdef XJF_TUXEDO
#include <fml32.h>
#include <atmi.h>
#include <tpadm.h>
#include <userlog.h>
#endif

#ifdef __WIN32__
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif

namespace XJUtilClass {

int XJF::m_nERRNO = XJ_RET_SUCC;

XJF::XJF(const string &strName, const char* pValue, const XJT32U &nLen, const enum XJF_TYPE nType) {
	m_pParent = 0;
	m_pPrev = 0;
	m_pNext = 0;
	m_pFirstChild = 0;
	m_pLastChild = 0;
	SetName(strName);
	m_nType = nType;
	SetValue(pValue, nLen, 0);
}

XJF::XJF(const string &strName, enum XJF_TYPE nType){
	m_pParent = 0;
	m_pPrev = 0;
	m_pNext = 0;
	m_pFirstChild = 0;
	m_pLastChild = 0;
	SetName(strName);
	m_nType = nType;
}
XJF *XJF::New(const string &strName, const char* pValue, const XJT32U &nLen, const enum XJF_TYPE nType){
	return new XJF(strName, pValue, nLen, nType);
}

XJF::~XJF() {
	m_veValue.clear();
	XJF* node = m_pFirstChild, *temp = 0;
	while ( node )
	{
		temp = node;
		node = node-> m_pNext;
		delete temp;// 子析构时,子子删除
	}
}

void XJF::Clear(){
	XJF* node = m_pFirstChild, *temp = 0;
	while ( node )
	{
		temp = node;
		node = node->m_pNext;
		delete temp; // 子析构时,子子删除
	}
	m_pFirstChild = 0;
	m_pLastChild = 0;
}

const XJF* XJF::FirstChild( const string &strName ) const
{
	const XJF* node;
	for ( node = m_pFirstChild; node; node = node->m_pNext )
	{
		if ( node->m_strName == strName )
			return node;
	}
	return 0;
}

const XJF* XJF::LastChild( const string &strName ) const
{
	const XJF* node;
	for ( node = m_pLastChild; node; node = node->m_pPrev )
	{
		if ( node->m_strName == strName )
			return node;
	}
	return 0;
}

const XJF* XJF::IterateChildren( const XJF* previous ) const
{
	if ( !previous )
	{
		return FirstChild();
	}
	else
	{
		assert( previous->m_pParent == this );
		return previous->NextSibling();
	}
}

const XJF* XJF::IterateChildren(const string &strName, const XJF* previous ) const
{
	if ( !previous )
	{
		return FirstChild( strName );
	}
	else
	{
		assert( previous->m_pParent == this );
		return previous->NextSibling( strName );
	}
}

const XJF* XJF::NextSibling( const string &strName ) const
{
	const XJF* node;
	for ( node = m_pNext; node; node = node->m_pNext )
	{
		if ( node->m_strName == strName )
			return node;
	}
	return 0;
}

const XJF* XJF::PreviousSibling( const string &strName ) const
{
	const XJF* node;
	for ( node = m_pPrev; node; node = node->m_pPrev )
	{
		if ( node->m_strName == strName )
			return node;
	}
	return 0;
}

XJF* XJF::InsertFirstChild( XJF* node )
{
	if (node->m_pParent != NULL){
		m_nERRNO = XJ_RET_F_HAS_PARENT;
		return 0;
	}
	if ( m_nType != XJF::TYPE_OBJECT && m_nType != XJF::TYPE_ARRAY )
	{
		m_nERRNO = XJ_RET_F_NOT_PARENT;
		return 0;
	}

	node->m_pParent = this;

	node->m_pPrev = 0;
	node->m_pNext = m_pFirstChild;

	if ( m_pFirstChild )
		m_pFirstChild->m_pPrev = node;
	else
		m_pLastChild = node;			// it was an empty list.

	m_pFirstChild = node;
	return node;
}

XJF* XJF::InsertLastChild( XJF* node )
{
	if (node->m_pParent != NULL){
		m_nERRNO = XJ_RET_F_HAS_PARENT;
		return 0;
	}
	if ( m_nType != XJF::TYPE_OBJECT && m_nType != XJF::TYPE_ARRAY )
	{
		m_nERRNO = XJ_RET_F_NOT_PARENT;
		return 0;
	}

	node->m_pParent = this;

	node->m_pPrev = m_pLastChild;
	node->m_pNext = 0;

	if ( m_pLastChild )
		m_pLastChild->m_pNext = node;
	else
		m_pFirstChild = node;			// it was an empty list.

	m_pLastChild = node;
	return node;
}

XJF* XJF::InsertBeforeChild( XJF* beforeThis, XJF* node ){
	if (node->m_pParent != NULL)
	{
		m_nERRNO = XJ_RET_F_HAS_PARENT;
		return 0;
	}
	if (beforeThis->m_pParent != this)
	{
		m_nERRNO = XJ_RET_F_NOT_PARENT;
		return 0;
	}
	if ( m_nType != XJF::TYPE_OBJECT &&  m_nType != XJF::TYPE_ARRAY )
	{
		//return 0;
	}
	XJF* beforeBeforeThis = beforeThis->m_pPrev;
	// beforeBeforeThis,node,beforeThis
	node->m_pParent = this;
	if (beforeThis != beforeBeforeThis){
		node->m_pPrev = beforeBeforeThis;
		node->m_pNext = beforeThis;
		beforeBeforeThis->m_pNext = node;
		beforeThis->m_pPrev = node;
	}else{
		node->m_pPrev = 0;
		node->m_pNext = beforeThis;
		m_pFirstChild = node;
	}
	return node;
}
XJF* XJF::InsertAfterChild(  XJF* afterThis, XJF* node ){
	if (node->m_pParent != NULL)
	{
		m_nERRNO = XJ_RET_F_HAS_PARENT;
		return 0;
	}
	if (afterThis->m_pParent != this)
	{
		m_nERRNO = XJ_RET_F_DEFF_PARENT;
		return 0;
	}
	if ( m_nType != XJF::TYPE_OBJECT && m_nType != XJF::TYPE_ARRAY )
	{
		//return 0;
	}
	XJF* afterAfterThis = afterThis->m_pNext;
	// afterThis,node,afterAfterThis
	node->m_pParent = this;
	if (afterAfterThis != afterThis){
		node->m_pPrev = afterThis;
		node->m_pNext = afterAfterThis;
		afterThis->m_pNext = node;
		afterAfterThis->m_pPrev = node;
	}else{
		node->m_pPrev = afterThis;
		node->m_pNext = 0;
		m_pLastChild = node;
	}
	return node;
}
XJF* XJF::ReplaceChild( XJF* replaceThis, XJF* node ){
	if (node->m_pParent != NULL)
	{
		m_nERRNO = XJ_RET_F_HAS_PARENT;
		return 0;
	}
	if (replaceThis->m_pParent != this)
	{
		m_nERRNO = XJ_RET_F_DEFF_PARENT;
		return 0;
	}
	if ( m_nType != XJF::TYPE_OBJECT && m_nType != XJF::TYPE_ARRAY )
	{
		//return 0;
	}
	node->m_pParent = this;
	node->m_pNext = replaceThis->m_pNext;
	node->m_pPrev = replaceThis->m_pPrev;

	if ( replaceThis->m_pNext )
		replaceThis->m_pNext->m_pPrev = node;
	else
		m_pLastChild = node;

	if ( replaceThis->m_pPrev )
		replaceThis->m_pPrev->m_pNext = node;
	else
		m_pFirstChild = node;
	delete replaceThis;
	return node;
}

bool XJF::RemoveChild( XJF* removeThis ){
	if ( !removeThis ) {
		m_nERRNO = XJ_RET_F_IS_NULL;
		return false;
	}
	if ( removeThis->m_pParent != this )
	{
		m_nERRNO = XJ_RET_F_DEFF_PARENT;
		return false;
	}
	if ( removeThis->m_pNext )
		removeThis->m_pNext->m_pPrev = removeThis->m_pPrev;
	else
		m_pLastChild = removeThis->m_pPrev;

	if ( removeThis->m_pPrev )
		removeThis->m_pPrev->m_pNext = removeThis->m_pNext;
	else
		m_pFirstChild = removeThis->m_pNext;

	delete removeThis;
	return true;
}

XJF* XJF::NewDuplicate(XJF* pF){
	if(0 == pF){
		return 0;
	}
	XJT32U nBufLen = pF->GetBufLen();
	char *pBuf = new char[nBufLen];
	memset(pBuf, 0 ,nBufLen);
	pF->ToBuf(pBuf, nBufLen);
	XJF *pFTmp = NewFromBuf(pBuf, nBufLen);
	delete pBuf;
	return pFTmp;
}

const XJT32U XJF::GetValueLen(const XJT32U &nIndex){
	XJT32U nLen = 0;
	string strValue;
	if (nIndex < m_veValue.size()){
		strValue = m_veValue[nIndex];
	}else{
		return nLen;
	}
	if (strValue.size() == 0){
		return nLen;
	}
	switch (m_nType){
	case XJF::TYPE_SHORT:
		nLen = sizeof(unsigned short );
		break;
	case XJF::TYPE_LONG:
		nLen = sizeof(XJT32U);
		break;
	case XJF::TYPE_CHAR:
		nLen = sizeof(unsigned char );
		break;
	case XJF::TYPE_FLOAT:
		nLen = sizeof(float );
		break;
	case XJF::TYPE_DOUBLE:
		nLen = sizeof(double );
		break;
	case XJF::TYPE_STRING:
#ifdef XJFSTRING_HEX
#else
		nLen = strValue.size();
		break;
#endif
	case XJF::TYPE_CARRAY:
		nLen = strValue.size()/2;
		break;
	case XJF::TYPE_PTR:
		nLen = sizeof(XJT32U);
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return 0;
	}
	return nLen;
}

int XJF::GetValue(char* pValue, XJT32U &nLen,const XJT32U &nIndex){
	if (NULL == pValue){
		m_nERRNO = XJ_RET_F_IS_NULL;
		return XJ_RET_F_IS_NULL;
	}
	string strValue;
	if (nIndex < m_veValue.size()){
		strValue = m_veValue[nIndex];
	}else{
		m_nERRNO = XJ_RET_F_INDEX_INVALID;
		return XJ_RET_F_INDEX_INVALID;
	}
	if (strValue.size() == 0){
		m_nERRNO = XJ_RET_F_SIZE_ZERO;
		return XJ_RET_F_SIZE_ZERO;
	}
	if (nLen < GetValueLen(nIndex)){
		m_nERRNO = XJ_RET_F_BUF_LEN_ERROR;
		return XJ_RET_F_BUF_LEN_ERROR;
	}
	nLen = GetValueLen(nIndex);
	XJT32U nValueLen = 0;
	char szAsc[3] = { 0 };
	unsigned long nAscLen = 3;
	char *pAsc = NULL;
	switch (m_nType){
	case XJF::TYPE_SHORT:
		(*((unsigned short *)pValue)) = XJSU::ToShort(strValue);
		break;
	case XJF::TYPE_LONG:
		if (sizeof(XJT32I) == 4){
			(*((XJT32I *)pValue)) = XJSU::ToLong(strValue);
		}else{
			(*((XJT32I *)pValue)) = XJSU::ToLongLong(strValue);
		}
		break;
	case XJF::TYPE_CHAR:
		memset(szAsc, 0, sizeof(szAsc));
		nAscLen = 3;
		XJHexString::HexToAsc(strValue.c_str(), strValue.size(), (unsigned char *)szAsc, nAscLen);
		(*((char *)pValue)) = szAsc[0];
		break;
	case XJF::TYPE_FLOAT:
		(*((float *)pValue)) = XJSU::ToFloat(strValue);
		break;
	case XJF::TYPE_DOUBLE:
		(*((double *)pValue)) = XJSU::ToDouble(strValue);
		break;
	case XJF::TYPE_STRING:
#ifdef XJFSTRING_HEX
#else
		memcpy(pValue, strValue.c_str(), nLen);
		break;
#endif
	case XJF::TYPE_CARRAY:
		nAscLen = strValue.size()/2+1;
		pAsc = new char[nAscLen];
		memset(pAsc,0,nAscLen);
		XJHexString::HexToAsc(strValue.c_str(), strValue.size(), (unsigned char *)pAsc, nAscLen);
		memcpy(pValue, pAsc, nValueLen);
		delete pAsc;
		pAsc = NULL;
		break;
	case XJF::TYPE_PTR:
		if (sizeof(XJT32I) == 4){
			(*((XJT32I *)pValue)) = XJSU::ToLong(strValue);
		}else{
			(*((XJT32I *)pValue)) = XJSU::ToLongLong(strValue);
		}
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return XJ_RET_F_TYPE_INVALID;
	}
	return 0;
}

int XJF::SetValue(const char* pValue, const XJT32U &nLen,const XJT32U &nIndex){
	if (NULL == pValue){
		return -1;
	}
	unsigned short sValue = 0;
	XJT32I lValue = 0;
	char chValue = 0;
	float fValue = 0.00;
	double dValue = 0.00;
	string strValue;
	char szAsc[3] = { 0 };
	char szHex[3] = { 0 };
	unsigned long nHexLen = 3;
	char *pHex = NULL;
	switch (m_nType){
	case XJF::TYPE_SHORT:
		sValue = (unsigned short)(*((unsigned short *)pValue));
		strValue = XJSU::FromLong(sValue);
		break;
	case XJF::TYPE_LONG:
		lValue = (XJT32I)(*((XJT32I *)pValue));
		if (sizeof(XJT32I) == 4){
			strValue = XJSU::FromLong(lValue);
		}else{
			strValue = XJSU::FromLongLong(lValue);
		}
		break;
	case XJF::TYPE_CHAR:
		chValue = (char)(*((char *)pValue));
		memset(szAsc,0,sizeof(szAsc));
		szAsc[0] = chValue;
		memset(szHex,0,sizeof(szHex));
		nHexLen = 3;
		XJHexString::AscToHex((unsigned char *)szAsc, 1, szHex, nHexLen);
		strValue = szHex;
		break;
	case XJF::TYPE_FLOAT:
		fValue = (*((float *)pValue));
		strValue = XJSU::FromDouble(fValue);
		break;
	case XJF::TYPE_DOUBLE:
		dValue = (*((double *)pValue));
		strValue = XJSU::FromDouble(dValue);
		break;
	case XJF::TYPE_STRING:
#ifdef XJFSTRING_HEX
#else
		strValue = pValue;
		break;
#endif
	case XJF::TYPE_CARRAY:
		strValue = pValue;
		nHexLen = nLen * 2+1;
		pHex = new char[nHexLen];
		if (NULL == pHex){
			m_nERRNO = XJ_RET_F_MALLOC_NULL;
			return XJ_RET_F_MALLOC_NULL;
		}
		memset(pHex, 0, nHexLen);
		XJHexString::AscToHex((unsigned char *)pValue, nLen, pHex, nHexLen);
		strValue = pHex;
		delete pHex;
		pHex = NULL;
		break;
	case XJF::TYPE_PTR:
		lValue = (XJT32I)(*((XJT32I *)pValue));
		if (sizeof(XJT32I) == 4){
			strValue = XJSU::FromLong(lValue);
		}else{
			strValue = XJSU::FromLongLong(lValue);
		}
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return XJ_RET_F_TYPE_INVALID;
	}
	while(m_veValue.size() <= nIndex){
		m_veValue.push_back("");
	}
	m_veValue[nIndex] = strValue;
	return 0;
}

int XJF::DelValue(const XJT32U &nIndex){
	if (nIndex >= m_veValue.size()){
		return -1;
	}
	vector<string>::iterator it = m_veValue.begin();
	it += nIndex;
	m_veValue.erase(it);
	return 0;
}

const XJT32U XJF::GetBufLen(const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	XJT32U nLen = 0,i=0;
	const unsigned short nLongLen = sizeof(XJT32U);
	nLen = nLongLen+1+1+pF->m_strName.size();
	XJF* pFTmp = NULL;
	switch (pF->m_nType){
	case XJF::TYPE_SHORT:
		nLen+=(sizeof(unsigned short)*pF->m_veValue.size());
		break;
	case XJF::TYPE_LONG:
		nLen+=(sizeof(XJT32U)*pF->m_veValue.size());
		break;
	case XJF::TYPE_CHAR:
		nLen+=(sizeof(char)*pF->m_veValue.size());
		break;
	case XJF::TYPE_FLOAT:
		nLen+=(sizeof(float)*pF->m_veValue.size());
		break;
	case XJF::TYPE_DOUBLE:
		nLen+=(sizeof(double)*pF->m_veValue.size());
		break;
	case XJF::TYPE_STRING:
#ifdef XJFSTRING_HEX
#else
		for(i=0;i<pF->m_veValue.size();i++){
			nLen+=(nLongLen+pF->m_veValue[i].size());
		}
		break;
#endif
	case XJF::TYPE_CARRAY:
		for(i=0;i<pF->m_veValue.size();i++){
			nLen+=(nLongLen+pF->m_veValue[i].size()/2);
		}
		break;
	case XJF::TYPE_PTR:
		nLen+=(sizeof(XJT32U)*pF->m_veValue.size());
		break;
	case XJF::TYPE_OBJECT:
	case XJF::TYPE_ARRAY:
		for(pFTmp= pF->m_pFirstChild;pFTmp;pFTmp=pFTmp->m_pNext){
			nLen+=GetBufLen(pFTmp);
		}
		break;
	case XJF::TYPE_NULL:
		nLen+=0;
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return 0;
	}
	return nLen;
}

int XJF::ToBuf(char *pBuf, XJT32U &nLen, const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	XJT32U i=0, nBufLen = GetBufLen(pF),nPos = 0, nValueLen;
	if (0 == nBufLen || nLen < nBufLen){
		m_nERRNO = XJ_RET_F_BUF_LEN_ERROR;
		return XJ_RET_F_BUF_LEN_ERROR;
	}
	nLen = nBufLen;
	unsigned short nLongLen = sizeof(XJT32U);
	XJT32U nNetLen = 0;
	if (sizeof(XJT32U) == 8){
		nNetLen = conv_htonll(nBufLen);
	}else{
		nNetLen = htonl(nBufLen);
	}
	nPos = 0;
	memcpy(pBuf+nPos, &nNetLen, nLongLen); // 总长度 sizeof(XJT32U)
	nPos = nLongLen;
	pBuf[nPos] = pF->m_nType; // 类型 1
	nPos+=1;
	pBuf[nPos] = pF->m_strName.size();// Name长度 1
	nPos+=1;
	memcpy(pBuf+nPos, pF->m_strName.c_str(), pF->m_strName.size()); // Name  N
	nPos+=pF->m_strName.size();
	unsigned short sNetValue = 0;
	XJT32U nNetValue = 0;
	char szAsc[3] = { 0 };
	unsigned long nAscLen = 3;
	char *pAsc = NULL;
	float  fValue = 0.00;
	double dValue = 0.00;
	string strValue;
	XJF* pFTmp = NULL;
	char *pBufTmp = NULL;
	//cout << "nBufLen:" << nBufLen << endl;
	//cout << "nNetLen:" << nNetLen << endl;
	switch (pF->m_nType){
	case XJF::TYPE_SHORT:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			sNetValue = htons(XJSU::ToShort(strValue));
			memcpy(pBuf+nPos, &sNetValue, sizeof(unsigned short));
			nPos+=sizeof(unsigned short);
		}
		break;
	case XJF::TYPE_LONG:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			if(nLongLen == 4){
				nNetValue = htonl(XJSU::ToULong(strValue));
			}else{
				nNetValue = conv_htonll(XJSU::ToULongLong(strValue));
			}
			memcpy(pBuf+nPos, &nNetValue, nLongLen);
			nPos+=nLongLen;
		}
		break;
	case XJF::TYPE_CHAR:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			memset(szAsc, 0, sizeof(szAsc));
			nAscLen = sizeof(szAsc);
			XJHexString::HexToAsc(strValue.c_str(), strValue.size(), (unsigned char *)szAsc, nAscLen);
			//szAsc[0];
			memcpy(pBuf+nPos, &szAsc[0], 1);
			nPos+=1;
		}
		break;
	case XJF::TYPE_FLOAT:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			fValue = XJSU::ToFloat(strValue);
			memcpy(pBuf+nPos, &fValue, sizeof(fValue));
			nPos+=sizeof(fValue);
		}
		break;
	case XJF::TYPE_DOUBLE:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			dValue = XJSU::ToDouble(strValue);
			memcpy(pBuf+nPos, &dValue, sizeof(dValue));
			nPos+=sizeof(dValue);
		}
		break;
	case XJF::TYPE_STRING:
#ifdef XJFSTRING_HEX
#else
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			nValueLen = strValue.size();
			if(nLongLen == 4){
				nNetValue = htonl(nValueLen);
			}else{
				nNetValue = conv_htonll(nValueLen);
			}
			memcpy(pBuf+nPos, &nNetValue, nLongLen);
			nPos+=nLongLen;
			memcpy(pBuf+nPos, strValue.c_str(),nValueLen);
			nPos+=nValueLen;
		}
		break;
#endif
	case XJF::TYPE_CARRAY:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			nValueLen = strValue.size()/2;
			nAscLen = nValueLen+1;
			pAsc = new char[nAscLen];
			memset(pAsc,0,nAscLen);
			XJHexString::HexToAsc(strValue.c_str(), strValue.size(), (unsigned char *)pAsc, nAscLen);
			if(nLongLen == 4){
				nNetValue = htonl(nValueLen);
			}else{
				nNetValue = conv_htonll(nValueLen);
			}
			memcpy(pBuf+nPos, &nNetValue, nLongLen);
			nPos+=nLongLen;
			memcpy(pBuf+nPos, pAsc,nValueLen);
			nPos+=nValueLen;
			delete pAsc;
			pAsc = NULL;
		}
		break;
	case XJF::TYPE_PTR:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			if(nLongLen == 4){
				nNetValue = htonl(XJSU::ToULong(strValue));
			}else{
				nNetValue = conv_htonll(XJSU::ToULongLong(strValue));
			}
			memcpy(pBuf+nPos, &nNetValue, nLongLen);
			nPos+=nLongLen;
		}
		break;
	case XJF::TYPE_OBJECT:
	case XJF::TYPE_ARRAY:
		for(pFTmp= pF->m_pFirstChild; pFTmp != NULL;pFTmp=pFTmp->m_pNext){
			nValueLen = GetBufLen(pFTmp);
			//cout << "nPos:"<< nPos << endl;
			//cout << "ToBuf pFTmp nValueLen:"<< nValueLen << endl;
			//cout << "ToBuf pFTmp->m_nType:"<< pFTmp->m_nType << endl;
			pBufTmp = new char[nValueLen];
			ToBuf(pBufTmp, nValueLen, pFTmp);
			memcpy(pBuf+nPos, pBufTmp, nValueLen);
			nPos+=nValueLen;
			delete pBufTmp;
			pBufTmp = NULL;
		}
		break;
	case XJF::TYPE_NULL:
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return XJ_RET_F_TYPE_INVALID;
	}
	return 0;
}

XJF * XJF::NewFromBuf(const char *pBuf,const XJT32U &nLen){
	return (XJF *)FromBuf(pBuf, nLen);
}

const XJF* XJF::FromBuf(const char *pBuf,const XJT32U &nLen){
	XJF *pF = NULL, *pFTmp = NULL;
	const unsigned short nLongLen = sizeof(XJT32U);
	XJT32U i=0,nPos = 0, nValueLen, nValueSize, nValueItemLen = 0, nTmp = 0, nValuePos = 0;
	XJT32U nNetLen = 0, nBufLen = 0;
	char  chType = 0;
	char  chNameSize = 0;
	char *pValueItem = NULL;
	memcpy(&nNetLen, pBuf+nPos, nLongLen); // 总长度 sizeof(XJT32U)
	nPos+=nLongLen;
	memcpy(&chType, pBuf+nPos, 1); // 类型 1
	nPos+=1;
	memcpy(&chNameSize, pBuf+nPos, 1); // Name长度 1
	nPos+=1;
	char *pName = new char[(chNameSize-'\0')+1];
	memset(pName, 0, (chNameSize-'\0')+1);
	memcpy(pName, pBuf+nPos, (chNameSize-'\0')); // Name N
	nPos+=(chNameSize-'\0');
	if (sizeof(XJT32U) == 8){
		nBufLen = conv_ntohll(nNetLen);
	}else{
		nBufLen = ntohl(nNetLen);
	}
	nValueLen = nBufLen - nPos;
	enum XJF_TYPE nType = (enum XJF_TYPE)(chType-'\0');
	unsigned short sNetValue=0, sValue = 0;
	XJT32U nValue=0;
	string strValue;
	unsigned char chValue = 0;
	float fValue = 0.00;
	double dValue = 0.00;
	//cout << "nType:" << nType << endl;
	switch (nType){
	case XJF::TYPE_SHORT:
		pF = (XJF *)XJFShort::NewFShort(pName, 0);
		nValueSize = nValueLen/sizeof(unsigned short);
		for(i=0;i<nValueSize;i++){
			memcpy(&sNetValue, pBuf+nPos, sizeof(unsigned short));
			nPos+=sizeof(unsigned short);
			sValue = ntohs(sNetValue);
			((XJFShort *)pF)->SetValue(sValue, i);
		}
		break;
	case XJF::TYPE_LONG:
		pF = (XJF *)XJFLong::NewFLong(pName, 0);
		nValueSize = nValueLen/nLongLen;
		for(i=0;i<nValueSize;i++){
			memcpy(&sNetValue, pBuf+nPos, nLongLen);
			nPos+=nLongLen;
			if (sizeof(XJT32U) == 8){
				nValue = conv_ntohll(nNetLen);
			}else{
				nValue = ntohl(nNetLen);
			}
			((XJFLong *)pF)->SetValue(nValue, i);
		}
		break;
	case XJF::TYPE_CHAR:
		pF = (XJF *)XJFChar::NewFChar(pName, 0);
		nValueSize = nValueLen/nLongLen;
		for(i=0;i<nValueSize;i++){
			memcpy(&chValue, pBuf+nPos, 1);
			nPos+=1;
			((XJFChar *)pF)->SetValue(chValue, i);
		}
		break;
	case XJF::TYPE_FLOAT:
		pF = (XJF *)XJFFloat::NewFFloat(pName, 0);
		nValueSize = nValueLen/sizeof(float);
		for(i=0;i<nValueSize;i++){
			memcpy(&fValue, pBuf+nPos, sizeof(float));
			nPos+=sizeof(float);
			((XJFFloat *)pF)->SetValue(fValue, i);
		}
		break;
	case XJF::TYPE_DOUBLE:
		pF = (XJF *)XJFDouble::NewFDouble(pName, 0);
		nValueSize = nValueLen/sizeof(double);
		for(i=0;i<nValueSize;i++){
			memcpy(&dValue, pBuf+nPos, sizeof(double));
			nPos+=sizeof(double);
			((XJFDouble *)pF)->SetValue(dValue, i);
		}
		break;
	case XJF::TYPE_STRING:
		pF = (XJF *)XJFString::NewFString(pName, "");
		i = 0;
		nValuePos = 0;
		while(nValueLen > nValuePos && nValueLen - nValuePos >= nLongLen){
			memcpy(&nNetLen, pBuf+nPos, nLongLen);
			nPos+=nLongLen;
			nValuePos+=nLongLen;
			if (sizeof(XJT32U) == 8){
				nValueItemLen = conv_ntohll(nNetLen);
			}else{
				nValueItemLen = ntohl(nNetLen);
			}
			if (nValueLen > nValuePos && nValueLen - nValuePos >= nValueItemLen){
				pValueItem = new char[nValueItemLen+1];
				memset(pValueItem, 0, nValueItemLen+1);
				memcpy(pValueItem, pBuf+nPos, nValueItemLen);
				nPos+=nValueItemLen;
				nValuePos+=nValueItemLen;
				((XJFString *)pF)->SetValue(pValueItem, i);
				delete pValueItem;
				pValueItem = NULL;
				i++;
			}else{
				break;
			}
		}
		break;
	case XJF::TYPE_CARRAY:
		pF = (XJF *)XJFCarray::NewFCarray(pName, NULL, 0);
		i = 0;
		nValuePos = 0;
		while(nValueLen > nValuePos && nValueLen - nValuePos >= nLongLen){
			memcpy(&nNetLen, pBuf+nPos, nLongLen);
			nPos+=nLongLen;
			nValuePos+=nLongLen;
			if (sizeof(XJT32U) == 8){
				nValueItemLen = conv_ntohll(nNetLen);
			}else{
				nValueItemLen = ntohl(nNetLen);
			}
			if (nValueLen > nValuePos && nValueLen - nValuePos >= nValueItemLen){
				pValueItem = new char[nValueItemLen+1];
				memset(pValueItem, 0, nValueItemLen+1);
				memcpy(pValueItem, pBuf+nPos, nValueItemLen);
				nPos+=nValueItemLen;
				nValuePos+=nValueItemLen;
				((XJFCarray *)pF)->SetValue(pValueItem, nValueItemLen, i);
				delete pValueItem;
				pValueItem = NULL;
				i++;
			}else{
				break;
			}
		}
		break;
	case XJF::TYPE_PTR:
		pF = (XJF *)XJFPTR::NewFPTR(pName, 0);
		nValueSize = nValueLen/nLongLen;
		for(i=0;i<nValueSize;i++){
			memcpy(&nNetLen, pBuf+nPos, nLongLen);
			nPos+=nLongLen;
			if (sizeof(XJT32U) == 8){
				nValue = conv_ntohll(nNetLen);
			}else{
				nValue = ntohl(nNetLen);
			}
			((XJFPTR *)pF)->SetValue(&nValue, i);
		}
		break;
	case XJF::TYPE_OBJECT:
		pF = (XJF *)XJFObject::NewFObject(pName);
		i = 0;
		nValuePos = 0;
		//cout << "OBJECT nValueLen:" << nValueLen << endl;
		while(nValueLen > nValuePos && nValueLen - nValuePos >= nLongLen){
			//cout << "OBJECT nPos:" << nPos << endl;
			memcpy(&nNetLen, pBuf+nPos, nLongLen);
			nPos+=nLongLen;
			nValuePos+=nLongLen;
			if (sizeof(XJT32U) == 8){
				nValueItemLen = conv_ntohll(nNetLen);
			}else{
				nValueItemLen = ntohl(nNetLen);
			}
			//cout << "OBJECT nNetLen:"<< nNetLen << endl;
			//cout << "OBJECT nValueItemLen:"<< nValueItemLen << endl;
			nValueItemLen = nValueItemLen - nLongLen;
			if (nValueLen > nValuePos && nValueLen - nValuePos >= nValueItemLen){
				nTmp = nLongLen + nValueItemLen;
				pValueItem = new char[nTmp];
				memset(pValueItem, 0, nTmp);
				memcpy(pValueItem, &nNetLen, nLongLen);
				memcpy(pValueItem+nLongLen, pBuf+nPos, nValueItemLen);
				nPos+=nValueItemLen;
				nValuePos+=nValueItemLen;
				pFTmp = (XJF *)FromBuf(pValueItem, nTmp);
				if (pFTmp){
					if (NULL == pF->InsertLastChild(pFTmp)){
						delete pFTmp;
					}
				}
				delete pValueItem;
				pValueItem = NULL;
				i++;
			}else{
				break;
			}
		}
		break;
	case XJF::TYPE_ARRAY:
		pF = (XJF *)XJFArray::NewFArray(pName);
		i = 0;
		nValuePos = 0;
		while(nValueLen > nValuePos && nValueLen - nValuePos >= nLongLen){
			memcpy(&nNetLen, pBuf+nPos, nLongLen);
			nPos+=nLongLen;
			nValuePos+=nLongLen;
			if (sizeof(XJT32U) == 8){
				nValueItemLen = conv_ntohll(nNetLen);
			}else{
				nValueItemLen = ntohl(nNetLen);
			}
			nValueItemLen = nValueItemLen - nLongLen;
			if (nValueLen > nValuePos && nValueLen - nValuePos >= nValueItemLen){
				nTmp = nLongLen + nValueItemLen;
				pValueItem = new char[nTmp];
				memset(pValueItem, 0, nTmp);
				memcpy(pValueItem, &nNetLen, nLongLen);
				memcpy(pValueItem+nLongLen, pBuf+nPos, nValueItemLen);
				nPos+=nValueItemLen;
				nValuePos+=nValueItemLen;
				pFTmp = (XJF *)FromBuf(pValueItem, nTmp);
				if (pFTmp){
					if (NULL == pF->InsertLastChild(pFTmp)){
						delete pFTmp;
					}
				}
				i++;
			}else{
				break;
			}
		}
		break;
	case XJF::TYPE_NULL:
		pF = (XJF *)XJF::New(pName, NULL, 0, XJF::TYPE_NULL);
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		break;
	}
	return pF;
}
#ifdef XJF_JSON
const XJT32U XJF::GetJsonLen(bool bJsonPretty, const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	XJT32U nRet = 0;
	json_object *pJsonObject = NULL;
	pJsonObject = (json_object *)ToJsonObject(pF);
	if (pJsonObject != NULL){
		char *p = NULL;
		if (bJsonPretty){
			p = (char *)json_object_to_json_string_ext(pJsonObject, JSON_C_TO_STRING_PRETTY);
		}else{
			p = (char *)json_object_to_json_string(pJsonObject);
		}
		if (p){
			nRet = strlen(p)+1;
		}else{
			m_nERRNO = XJ_RET_F_JSON_TO_STR_NULL;
			//nRet = -2;
		}
		json_object_put(pJsonObject);
		pJsonObject = NULL;
	}else{
		m_nERRNO = XJ_RET_F_JSON_OBJECT_NULL;
		//nRet = -1;
	}
	return nRet;
}

int XJF::ToJson(char *pJson, XJT32U &nLen, bool bJsonPretty, const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	int nRet = 0;
	json_object *pJsonObject = NULL;
	pJsonObject = (json_object *)ToJsonObject(pF);

	if (pJsonObject != NULL){
		char *p = NULL;
		if (bJsonPretty){
			p = (char *)json_object_to_json_string_ext(pJsonObject, JSON_C_TO_STRING_PRETTY);
		}else{
			p = (char *)json_object_to_json_string(pJsonObject);
		}
		if (p){
			if (nLen > strlen(p)){
				nLen = strlen(p);
				strncpy(pJson, p, nLen);
			}else{
				m_nERRNO = XJ_RET_F_BUF_LEN_ERROR;
				nRet = XJ_RET_F_BUF_LEN_ERROR;
			}
		}else{
			m_nERRNO = XJ_RET_F_JSON_TO_STR_NULL;
			nRet = XJ_RET_F_JSON_TO_STR_NULL;
		}
		json_object_put(pJsonObject);
		pJsonObject = NULL;
	}else{
		m_nERRNO = XJ_RET_F_JSON_OBJECT_NULL;
		nRet = XJ_RET_F_JSON_OBJECT_NULL;
	}
	return nRet;
}

string XJF::ToJson(bool bJsonPretty, const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	int nRet = 0;
	string strRet;
	json_object *pJsonObject = NULL;
	pJsonObject = (json_object *)ToJsonObject(pF);
	if (pJsonObject != NULL){
		char *p = NULL;
		if (bJsonPretty){
			p = (char *)json_object_to_json_string_ext(pJsonObject, JSON_C_TO_STRING_PRETTY);
		}else{
			p = (char *)json_object_to_json_string(pJsonObject);
		}
		if (p){
			strRet = p;
		}else{
			m_nERRNO = XJ_RET_F_JSON_TO_STR_NULL;
			nRet = XJ_RET_F_JSON_TO_STR_NULL;
		}
		json_object_put(pJsonObject);
		pJsonObject = NULL;
	}else{
		m_nERRNO = XJ_RET_F_JSON_OBJECT_NULL;
		nRet = XJ_RET_F_JSON_OBJECT_NULL;
	}
	return strRet;
}

void *XJF::ToJsonObject(const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	void *pRet = 0;
	XJT32U i;
	string strValue;
	XJF *pFTmp = NULL;
	json_object *pJsonObject = NULL;
	json_object *pJsonArray = NULL;
	switch (pF->m_nType){
	case XJF::TYPE_SHORT:
	case XJF::TYPE_LONG:
	case XJF::TYPE_CHAR:
	case XJF::TYPE_FLOAT:
	case XJF::TYPE_DOUBLE:
	case XJF::TYPE_STRING:
	case XJF::TYPE_CARRAY:
	case XJF::TYPE_PTR:
	case XJF::TYPE_NULL:
		pJsonObject = json_object_new_object();
		json_object_object_add(pJsonObject, "N", json_object_new_string(pF->m_strName.c_str()));
		json_object_object_add(pJsonObject, "T", json_object_new_string(XJSU::FromLong(pF->m_nType).c_str()));
		pJsonArray = json_object_new_array();
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = m_veValue[i];
			for(i=0;i<pF->m_veValue.size();i++){
				strValue = pF->m_veValue[i];
				json_object_array_add(pJsonArray, json_object_new_string(strValue.c_str()));
			}
		}
		json_object_object_add(pJsonObject, "V", pJsonArray);
		pRet = pJsonObject;
		break;
	case XJF::TYPE_OBJECT:
		pJsonObject = json_object_new_object();
		json_object_object_add(pJsonObject, "N", json_object_new_string(pF->m_strName.c_str()));
		json_object_object_add(pJsonObject, "T", json_object_new_string(XJSU::FromLong(pF->m_nType).c_str()));
		pJsonArray = json_object_new_object();
		for(pFTmp= pF->m_pFirstChild;pFTmp;pFTmp=pFTmp->m_pNext){
			json_object_object_add(pJsonArray,pFTmp->m_strName.c_str(), (json_object *)pFTmp->ToJsonObject());
		}
		json_object_object_add(pJsonObject, "V", pJsonArray);
		pRet = pJsonObject;
		break;
	case XJF::TYPE_ARRAY:
		pJsonObject = json_object_new_object();
		json_object_object_add(pJsonObject, "N", json_object_new_string(pF->m_strName.c_str()));
		json_object_object_add(pJsonObject, "T", json_object_new_string(XJSU::FromLong(pF->m_nType).c_str()));
		pJsonArray = json_object_new_array();
		for(pFTmp= pF->m_pFirstChild;pFTmp;pFTmp=pFTmp->m_pNext){
			json_object_array_add(pJsonArray, (json_object *)pFTmp->ToJsonObject());
		}
		json_object_object_add(pJsonObject, "V", pJsonArray);
		pRet = pJsonObject;
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		pRet = NULL;
		break;
	}
	return pRet;
}
/*
JSON标准格式如下：
{
"N": "SendFML",
"T": "10",
"V": {
	"167774278": {  // FQDCode
		"N": "167774278",
		"T": "5",
		"V": [ "10001" ]
	}
}
或者非标准格式
{
	"N": "FML",
	"V": {
		"FD_WD_PCode":{
			"N":"FD_WD_PCode",
			"V":"610000"
		},
		"FD_WD_Amount1":{
			"N":"FD_WD_Amount",
			"V":"100"
		},
		"FD_WD_LocalDate":{
			"V":["20140505", "20140506"]
		}
	}
}
 * */
XJF *XJF::NewFromJson(const char *pJson){
	XJF *pF = NULL;
	json_object *pJsonObject = NULL;
	pJsonObject = json_tokener_parse(pJson);
	if (pJsonObject){
		pF =  (XJF*)FromJsonObject(pJsonObject);
		json_object_put(pJsonObject);
		pJsonObject = 0;
	}else{
		m_nERRNO = XJ_RET_F_JSON_OBJECT_NULL;
	}
	return pF;
}
const XJF* XJF::FromJsonObject(void *pJsonObjectArg, const string &strNameArg){
	int i = 0;
	XJF *pF = NULL;
	XJF *pFTmp = NULL;
	json_object *pJsonObject = (json_object *)pJsonObjectArg,
			*pJsonN= NULL, *pJsonT= NULL, *pJsonV = NULL, *pJsonItem = NULL;
	//char *pStrN = NULL, *pStrT = NULL,*pStrV = NULL;
	string strN = strNameArg, strT, strV;
	if (pJsonObject){
		if (json_object_get_type(pJsonObject) == json_type_object){
			pJsonN = json_object_object_get(pJsonObject, "N");
			pJsonT = json_object_object_get(pJsonObject, "T");
			pJsonV = json_object_object_get(pJsonObject, "V");
			if (pJsonN){
				if (json_object_get_type(pJsonN) == json_type_string)
					strN = (char *)json_object_get_string(pJsonN);
				else if (json_object_get_type(pJsonN) == json_type_int)
					strN = XJSU::FromLong(json_object_get_int(pJsonN));
				else if (json_object_get_type(pJsonN) == json_type_double)
					strN = XJSU::FromDouble(json_object_get_double(pJsonN));
			}
			if (pJsonT){
				if (json_object_get_type(pJsonT) == json_type_string)
					strT = (char *)json_object_get_string(pJsonT);
				else if (json_object_get_type(pJsonT) == json_type_int)
					strT = XJSU::FromLong(json_object_get_int(pJsonT));
				else if (json_object_get_type(pJsonT) == json_type_double)
					strT = XJSU::FromDouble(json_object_get_double(pJsonT), 0);
			}
			if (strT.size() == 0){
				if (pJsonV){
					if (json_object_get_type(pJsonV) == json_type_string){
						strT = XJSU::FromLong(XJF::TYPE_STRING);
					}else if (json_object_get_type(pJsonV) == json_type_int){
						strT = XJSU::FromLong(XJF::TYPE_LONG);
					}else if (json_object_get_type(pJsonV) == json_type_double){
						strT = XJSU::FromLong(XJF::TYPE_DOUBLE);
					}else if (json_object_get_type(pJsonV) == json_type_boolean){
						strT = XJSU::FromLong(XJF::TYPE_LONG);
					}else if (json_object_get_type(pJsonV) == json_type_null){
						strT = XJSU::FromLong(XJF::TYPE_NULL);
					}else if (json_object_get_type(pJsonV) == json_type_array){
						if (json_object_array_length(pJsonV)){
							pJsonItem = json_object_array_get_idx(pJsonV, 0);
							if (pJsonItem && json_object_get_type(pJsonItem) == json_type_string){
								strT = XJSU::FromLong(XJF::TYPE_STRING);
							}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_int){
								strT = XJSU::FromLong(XJF::TYPE_LONG);
							}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_double){
								strT = XJSU::FromLong(XJF::TYPE_DOUBLE);
							}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_boolean){
								strT = XJSU::FromLong(XJF::TYPE_LONG);
							}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_null){
								strT = XJSU::FromLong(XJF::TYPE_NULL);
							}else if(pJsonItem && json_object_get_type(pJsonItem) == json_type_array){
								strT = XJSU::FromLong(XJF::TYPE_ARRAY);
							}else if(pJsonItem && json_object_get_type(pJsonItem) == json_type_object){
								strT = XJSU::FromLong(XJF::TYPE_ARRAY);
							}
						}
					}else if(json_object_get_type(pJsonV) == json_type_object){
						strT = XJSU::FromLong(XJF::TYPE_OBJECT);
					}
				}
			}
			if (strT.size() == 0){
				printf("XJF::FromJsonObject N:%s error type.\n", strN.c_str());
				m_nERRNO = XJ_RET_F_TYPE_INVALID;
				return 0;
			}
			enum XJF_TYPE nType =  (enum XJF_TYPE)XJSU::ToInt(strT);
			pF = new XJF(strN, nType);
			switch (nType){
				case XJF::TYPE_SHORT:
				case XJF::TYPE_LONG:
				case XJF::TYPE_CHAR:
				case XJF::TYPE_FLOAT:
				case XJF::TYPE_DOUBLE:
				case XJF::TYPE_STRING:
				case XJF::TYPE_CARRAY:
				case XJF::TYPE_PTR:
				case XJF::TYPE_NULL:
					if (pJsonV){
						if (json_object_get_type(pJsonV) == json_type_string){
							strV = (char *)json_object_get_string(pJsonV);
							pF->m_veValue.push_back(strV);
						}else if (json_object_get_type(pJsonV) == json_type_int){
							strV = XJSU::FromLong(json_object_get_int(pJsonV));
							pF->m_veValue.push_back(strV);
						}else if (json_object_get_type(pJsonV) == json_type_double){
							strV = XJSU::FromDouble(json_object_get_double(pJsonV));
							pF->m_veValue.push_back(strV);
						}else if (json_object_get_type(pJsonV) == json_type_boolean){
							strV = XJSU::FromLong(json_object_get_boolean(pJsonV));
							pF->m_veValue.push_back(strV);
						}else if (json_object_get_type(pJsonV) == json_type_null){
							strV = "";
							pF->m_veValue.push_back(strV);
						}else if (json_object_get_type(pJsonV) == json_type_array){
							if (json_object_array_length(pJsonV)){
								for(i=0;i<json_object_array_length(pJsonV);i++){
									strV = "";
									pJsonItem = json_object_array_get_idx(pJsonV, i);
									if (pJsonItem && json_object_get_type(pJsonItem) == json_type_string){
										strV = (char *)json_object_get_string(pJsonItem);
									}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_int){
										strV = XJSU::FromLong(json_object_get_int(pJsonItem));
									}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_double){
										strV = XJSU::FromDouble(json_object_get_double(pJsonItem));
									}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_boolean){
										strV = XJSU::FromLong(json_object_get_boolean(pJsonItem));
									}else if (pJsonItem && json_object_get_type(pJsonItem) == json_type_null){

									}
									pF->m_veValue.push_back(strV);
								}
							}
						}
					}
				break;
				case XJF::TYPE_OBJECT:
					if(pJsonV && json_object_get_type(pJsonV) == json_type_object){
						json_object_object_foreach(pJsonV, key, val){
							if (val && json_object_get_type(val) == json_type_object){
								pFTmp = (XJF*)FromJsonObject((void *)val, key);
								if(pFTmp)
									pF->InsertLastChild(pFTmp);
							}
						}
					}
					break;
				case XJF::TYPE_ARRAY:
					if(pJsonV && json_object_get_type(pJsonV) == json_type_array){
						for(i=0;i<json_object_array_length(pJsonV);i++){
							pJsonItem = json_object_array_get_idx(pJsonV, i);
							if (pJsonItem && json_object_get_type(pJsonItem) == json_type_object){
								pFTmp =  (XJF*)FromJsonObject(pJsonItem);
								if(pFTmp)
									pF->InsertLastChild(pFTmp);
							}
						}
					}
					break;
				default:
					m_nERRNO = XJ_RET_F_TYPE_INVALID;
					break;
			}//switch (nType)
		}
	}
	return pF;
}
#endif
#ifdef XJF_TUXEDO
XJFObject * XJF::NewFromFML(void* pFMLData, bool bTranFldName){
	FBFR32* pFml = NULL;
	if (NULL == pFMLData){
		m_nERRNO = XJ_RET_F_IS_NULL;
		return 0;
	}
	pFml = (FBFR32*) pFMLData;
	char szErr[256]={0};
	const unsigned int nFML_FLD_BUF_LEN = 4096;
	FLDID32 fid,oldfid;
	FLDLEN32 nLen = 0;
	FLDOCC32 occ;
	long lLen = 0, iErrNO = 0, i = 0, y = 0, m = 0, lValue = 0;
	int iRet = 0, iType = 0, iValue = 0, nOccurNum, nCountNum;
	short sValue = 0;
	float fValue = 0.00;
	double dValue = 0.00;
	char chValue = '\0';
	//char szValue[nFML_FLD_BUF_LEN] = { 0x00 };
	char *szValue = new char[nFML_FLD_BUF_LEN];
	char szTmp[256] = { 0x00 };

	string strValue;
	XJUtilClass::XJF *pF = NULL;
	XJUtilClass::XJF *pFOld = NULL;
	FBFR32* pFmlSub = NULL;
	long nFMXJize = 0;
	XJFObject *pFObject = NewFObject("FML");

	string strN;

	for(fid=FIRSTFLDID,nLen=nFML_FLD_BUF_LEN, oldfid=FIRSTFLDID;
			(iRet = Fnext32(pFml, &fid, &occ, NULL, NULL)) > 0;) {
		nLen=nFML_FLD_BUF_LEN;
		memset(szValue, 0x00, nFML_FLD_BUF_LEN);
		iType = Fldtype32(fid);
		strN = XJSU::FromULong(fid);
		if (bTranFldName){
			if (Fname32(fid))strN = Fname32(fid);
		}
		pFOld = pF = pFObject->FirstChild(strN);
		if (FLD_SHORT == iType){
			if (Fget32(pFml, fid, occ, (char *)&sValue, NULL) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				//if (bToFldName)

				pF = (XJF *)XJUtilClass::XJF::NewFShort(strN, 0);
			}
			pF->ToFShort()->SetValue(sValue, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld, value:%d", iType, fid, occ, sValue);
		}else if(FLD_LONG == iType){
			if (Fget32(pFml, fid, occ, (char *)&lValue, NULL) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				pF = (XJF *)XJUtilClass::XJF::NewFLong(strN, 0);
			}
			pF->ToFLong()->SetValue(lValue, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld, value:%ld", iType, fid, occ, lValue);
		}else if(FLD_CHAR == iType){
			if (Fget32(pFml, fid, occ, (char *)&chValue,  NULL) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				pF = (XJF *)XJUtilClass::XJF::NewFChar(strN, 0);
			}
			pF->ToFChar()->SetValue(chValue, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld, value:%d", iType, fid, occ, chValue);
		}else if(FLD_FLOAT == iType){
			if (Fget32(pFml, fid, occ, (char *)&fValue, NULL) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				pF = (XJF *)XJUtilClass::XJF::NewFFloat(strN, 0.00);
			}
			pF->ToFFloat()->SetValue(fValue, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld, value:%f", iType, fid, occ, fValue);
		}else if(FLD_DOUBLE == iType){
			if (Fget32(pFml, fid, occ, (char *)&dValue, NULL) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				pF = (XJF *)XJUtilClass::XJF::NewFDouble(strN, 0.00);
			}
			pF->ToFDouble()->SetValue(dValue, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld, value:%lf", iType, fid, occ, dValue);
		}else if(FLD_STRING  == iType){
			if (Fget32(pFml, fid, occ, szValue, (FLDLEN32*)&nLen) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				pF = (XJF *)XJUtilClass::XJF::NewFString(strN, "");
			}
			pF->ToFString()->SetValue(szValue, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld, value:%s", iType, fid,  occ,  szValue);
		}else if(FLD_CARRAY == iType){
			if (Fget32(pFml, fid, occ, szValue, (FLDLEN32*)&nLen) < 0){
				snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
				continue;
			}
			if (NULL == pF){
				pF = (XJF *)XJUtilClass::XJF::NewFCarray(strN, "", 0);
			}
			pF->ToFCarray()->SetValue(szValue, nLen, occ);
			//printf("Fid Data:type:%d, fid:%ld, index:%ld", iType, fid, occ);
		}else if(FLD_FML32 == iType){
			nFMXJize = 4096;
			pFmlSub = (FBFR32 *)tpalloc((char*)"FML32", NULL, nFMXJize);
			if (pFmlSub){
				Finit32(pFmlSub, (FLDLEN32)nFMXJize);
				if (Fget32(pFml, fid, occ, (char *)&pFmlSub, (FLDLEN32*)&nLen) < 0){
					snprintf(szErr,sizeof(szErr)-1,"Fget32 error.Fid Data:type:%d, fid:%ld, index:%ld, Ferror32=%d", iType, fid, occ, Ferror32);
					continue;
				}
				if (NULL == pF){
					pF = NewFromFML(pFmlSub);
					if (pF && pF->ToFObject()){
						pF->SetName(strN);
					}
				}
				tpfree((char *)pFmlSub);
				pFmlSub = 0;
			}
			//printf("Fid Data:type:%d, fid:%ld, index:%ld", iType, fid, occ);
		}else{
			//printf("Fid Data:type:%d, fid:%ld, index:%ld", iType, fid, occ);
		}
		if (NULL == pFOld){
			pFObject->InsertLastChild(pF);
		}
		nLen=nFML_FLD_BUF_LEN,memset(szValue, 0x00, nFML_FLD_BUF_LEN);
	}
	return pFObject;
}

int  XJF::ToFML(void* pFMLData, const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	if (pF->m_nType != XJF::TYPE_OBJECT){
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return XJ_RET_F_TYPE_INVALID;
	}
	XJF* pFTmp = NULL;
	for(pFTmp= pF->m_pFirstChild; pFTmp != NULL;pFTmp=pFTmp->m_pNext){
		FObjectToFML(pFMLData, pFTmp);
	}
	return 0;
}
int XJF::FObjectToFML(void* pFMLData, const XJF* pF){
	if (NULL == pF){
		pF = this;
	}
	FBFR32* pFml = NULL;
	if (NULL == pFMLData){
		return 0;
	}
	pFml = (FBFR32*) pFMLData;
	XJT32U i=0, nValueLen;
	unsigned short nLongLen = sizeof(XJT32U);
	unsigned short sNetValue = 0;
	XJT32U nNetValue = 0;
	char szAsc[3] = { 0 };
	unsigned long nAscLen = 3;
	char *pAsc = NULL;
	float  fValue = 0.00;
	double dValue = 0.00;
	string strValue;
	XJF* pFTmp = NULL;
	FBFR32 *pFMLTmp = 0;
	long nFMXJize = 0;
	FLDID32 nFLDID32;
	if (XJSU::IsNum(pF->m_strName))
		nFLDID32 = XJSU::ToULong(pF->m_strName);
	else
		nFLDID32 = Fldid32((char *)pF->m_strName.c_str());
	switch (Fldtype32(nFLDID32)){
	case XJF::TYPE_SHORT:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			sNetValue = htons(XJSU::ToShort(strValue));
			Fchg32(pFml, nFLDID32, i, (char *)&sNetValue, sizeof(unsigned short));
		}
		break;
	case XJF::TYPE_LONG:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			Fchg32(pFml, nFLDID32, i, (char *)&nNetValue, nLongLen);
		}
		break;
	case XJF::TYPE_CHAR:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			memset(szAsc, 0, sizeof(szAsc));
			nAscLen = sizeof(szAsc);
			XJHexString::HexToAsc(strValue.c_str(), strValue.size(), (unsigned char *)szAsc, nAscLen);
			//szAsc[0];
			Fchg32(pFml, nFLDID32, i, (char *)&szAsc[0], nLongLen);
		}
		break;
	case XJF::TYPE_FLOAT:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			fValue = XJSU::ToFloat(strValue);
			Fchg32(pFml, nFLDID32, i, (char *)&fValue, sizeof(fValue));
		}
		break;
	case XJF::TYPE_DOUBLE:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			dValue = XJSU::ToDouble(strValue);
			Fchg32(pFml, nFLDID32, i, (char *)&dValue, sizeof(dValue));
		}
		break;
	case XJF::TYPE_STRING:
#ifdef XJFSTRING_HEX
#else
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			nValueLen = strValue.size();
			Fchg32(pFml, nFLDID32, i, (char *)strValue.c_str(), sizeof(nValueLen));
		}
		break;
#endif
	case XJF::TYPE_CARRAY:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			nValueLen = strValue.size()/2;
			nAscLen = nValueLen+1;
			pAsc = new char[nAscLen];
			memset(pAsc,0,nAscLen);
			XJHexString::HexToAsc(strValue.c_str(), strValue.size(), (unsigned char *)pAsc, nAscLen);
			Fchg32(pFml, nFLDID32, i, (char *)pAsc, sizeof(nValueLen));
			delete pAsc;
			pAsc = NULL;
		}
		break;
	case XJF::TYPE_PTR:
		for(i=0;i<pF->m_veValue.size();i++){
			strValue = pF->m_veValue[i];
			Fchg32(pFml, nFLDID32, i, (char *)&nNetValue, nLongLen);
		}
		break;
	case XJF::TYPE_OBJECT:
	case XJF::TYPE_ARRAY:
		nFMXJize = 4096;
		pFMLTmp = (FBFR32 *)tpalloc((char*)"FML32", NULL, nFMXJize);
		if (pFMLTmp){
			Finit32(pFMLTmp, (FLDLEN32)nFMXJize);
			for(pFTmp= pF->m_pFirstChild; pFTmp != NULL;pFTmp=pFTmp->m_pNext){
				FObjectToFML(pFml, pFTmp);
			}
			Fchg32(pFml, nFLDID32, i, (char *)pFMLTmp, nFMXJize);
			tpfree((char *)pFMLTmp);
			pFMLTmp = NULL;
		}
		break;
	case XJF::TYPE_NULL:
		break;
	default:
		m_nERRNO = XJ_RET_F_TYPE_INVALID;
		return XJ_RET_F_TYPE_INVALID;
	}
	return 0;
}
#endif

uint64_t XJF::conv_htonll(uint64_t v) {
    union UNITest u1, u2;
    u1.val = v;
    u2.st.val2 = htonl(u1.st.val1);
    u2.st.val1 = htonl(u1.st.val2);
    char cBuf[64]={0x00};
    snprintf(cBuf,64,"%lld",u2.val);
    return atoll(cBuf);
}

uint64_t XJF::conv_ntohll(uint64_t v) {
    union UNITest u1, u2;
    u1.val = v;
    u2.st.val2 = ntohl(u1.st.val1);
    u2.st.val1 = ntohl(u1.st.val2);
    char cBuf[64]={0x00};
    snprintf(cBuf,64,"%lld",u2.val);
    return atoll(cBuf);
}

XJFObject::XJFObject(const string &strName):
	XJF(strName, XJF::TYPE_OBJECT){

}
XJFObject *XJF::NewFObject(const string &strName){
	return (XJFObject *)New(strName, NULL, 0, XJF::TYPE_OBJECT);
}
XJFArray::XJFArray(const string &strName):
	XJF(strName, XJF::TYPE_ARRAY){
}

XJFArray *XJF::NewFArray(const string &strName){
	return (XJFArray *)New(strName, NULL, 0, XJF::TYPE_ARRAY);
}

XJFShort::XJFShort(const string &strName, const unsigned short &sValue):
	XJF(strName, (char *)&sValue, sizeof(unsigned short), XJF::TYPE_SHORT){
}

XJFShort *XJF::NewFShort(const string &strName, const unsigned short &sValue){
	return (XJFShort *)New(strName, (char *)&sValue, sizeof(unsigned short), XJF::TYPE_SHORT);
}

int XJFShort::GetValue(unsigned short &sValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(unsigned short);
	return XJF::GetValue((char *)&sValue, nLen, nIndex);
}
int XJFShort::SetValue(const unsigned short &sValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(unsigned short);
	return XJF::SetValue((char *)&sValue, nLen, nIndex);
}
XJFLong::XJFLong(const string &strName, const XJT32U &nValue):
	XJF(strName, (char *)&nValue, sizeof(XJT32U), XJF::TYPE_LONG){
}
XJFLong *XJF::NewFLong(const string &strName, const XJT32U &nValue){
	return (XJFLong *)New(strName, (char *)&nValue, sizeof(XJT32U), XJF::TYPE_LONG);
}
int XJFLong::GetValue(XJT32U &nValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(XJT32U);
	return XJF::GetValue((char *)&nValue, nLen, nIndex);
}
int XJFLong::SetValue(const XJT32U &nValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(XJT32U);
	return XJF::SetValue((char *)&nValue, nLen, nIndex);
}
XJFChar::XJFChar(const string &strName, const unsigned char &chValue):
	XJF(strName, (char *)&chValue, sizeof(unsigned char), XJF::TYPE_CHAR){
}
XJFChar *XJF::NewFChar(const string &strName, const unsigned char &chValue){
	return (XJFChar *)New(strName, (char *)&chValue, sizeof(unsigned char), XJF::TYPE_CHAR);
}
int XJFChar::GetValue(unsigned char &chValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(unsigned char);
	return XJF::GetValue((char *)&chValue, nLen, nIndex);
}
int XJFChar::SetValue(const unsigned char &chValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(unsigned char);
	return XJF::SetValue((char *)&chValue, nLen, nIndex);
}
XJFFloat::XJFFloat(const string &strName, const float &fValue):
		XJF(strName, (char *)&fValue, sizeof(float), XJF::TYPE_FLOAT){
}
XJFFloat *XJF::NewFFloat(const string &strName, const float &fValue){
	return (XJFFloat *)New(strName, (char *)&fValue, sizeof(float), XJF::TYPE_FLOAT);
}
int XJFFloat::GetValue(float &fValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(float);
	return XJF::GetValue((char *)&fValue, nLen, nIndex);
}
int XJFFloat::SetValue(const float &fValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(float);
	return XJF::SetValue((char *)&fValue, nLen, nIndex);
}
XJFDouble::XJFDouble(const string &strName, const double &dValue):
	XJF(strName, (char *)&dValue, sizeof(double), XJF::TYPE_DOUBLE){
}

XJFDouble *XJF::NewFDouble(const string &strName, const double &dValue){
	return (XJFDouble *)New(strName, (char *)&dValue, sizeof(double), XJF::TYPE_DOUBLE);
}
int XJFDouble::GetValue(double &dValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(double);
	return XJF::GetValue((char *)&dValue, nLen, nIndex);
}
int XJFDouble::SetValue(const double &dValue,const XJT32U &nIndex){
	XJT32U nLen = sizeof(double);
	return XJF::SetValue((char *)&dValue, nLen, nIndex);
}
XJFString::XJFString(const string &strName, const string &strValue):
	XJF(strName, (char *)strValue.c_str(), strValue.size(), XJF::TYPE_STRING){
}
XJFString *XJF::NewFString(const string &strName, const string &strValue){
	return (XJFString *)New(strName, (char *)strValue.c_str(), strValue.size(), XJF::TYPE_STRING);
}

int XJFString::GetValue(string &strValue,const XJT32U &nIndex){
	XJT32U nLen = GetValueLen(nIndex);
	if (nLen == 0){
		return 0;
	}
	int nRet = 0;
	char *pValue = new char[nLen+1];
	memset(pValue, 0, nLen+1);
	nRet = XJF::GetValue((char *)pValue, nLen, nIndex);
	strValue = pValue;
	return nRet;
}

int XJFString::SetValue(const string &strValue,const XJT32U &nIndex){
	XJT32U nLen = strValue.size();
	return XJF::SetValue((char *)strValue.c_str(), nLen, nIndex);
}

XJFCarray::XJFCarray(const string &strName, const char* pValue, const XJT32U &nLen):
		XJF(strName, (char *)&pValue, nLen, XJF::TYPE_CARRAY){
}

XJFCarray *XJF::NewFCarray(const string &strName, const char* pValue, const XJT32U &nLen){
	return (XJFCarray *)New(strName, (char *)&pValue, nLen, XJF::TYPE_CARRAY);
}
int XJFCarray::GetValue(char* pValue, XJT32U &nLen,const XJT32U &nIndex){
	XJT32U nOldLen = GetValueLen(nIndex);
	if (nOldLen == 0){
		nLen = 0;
		return 0;
	}
	int nRet = 0;
	char *pOldValue = new char[nOldLen+1];
	memset(pOldValue, 0, nOldLen+1);
	nRet = XJF::GetValue((char *)pOldValue, nOldLen, nIndex);
	if (nRet == 0){
		if (nLen >= nOldLen){
			nLen = nOldLen;
		}
		memcpy(pValue, pOldValue, nLen);
	}
	return nRet;
}
int XJFCarray::SetValue(const char* pValue, const XJT32U &nLen,const XJT32U &nIndex){
	return XJF::SetValue((char *)pValue, nLen, nIndex);
}

XJFPTR::XJFPTR(const string &strName, const void* pValue):
	XJF(strName, (char *)&pValue,XJF::TYPE_PTR){
}

XJFPTR *XJF::NewFPTR(const string &strName, const void* pValue){
	return (XJFPTR *)New(strName, (char *)&pValue,XJF::TYPE_PTR);
}

int XJFPTR::GetValue(void** ppValue,const XJT32U &nIndex){
	int nRet = 0;
	XJT32U nOldLen = GetValueLen(nIndex);
	nRet = XJF::GetValue((char *)ppValue, nOldLen, nIndex);
	return nRet;
}

int XJFPTR::SetValue(const void* pValue,const XJT32U &nIndex){
	XJT32U nOldLen = GetValueLen(nIndex);
	return XJF::SetValue((char *)&pValue, nOldLen, nIndex);
}

} /* namespace XJUtilClass */
